/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ontologia.servlets;

import com.ontologia.entities.Conceptos;
import com.ontologia.entities.Mediosdepropulsion;
import com.ontologia.entities.Mediosdetransportes;
import com.ontologia.entities.Ordenestrabajo;
import com.ontologia.entities.Paquetes;
import com.ontologia.session.ConceptosFacade;
import com.ontologia.session.MediosdepropulsionFacade;
import com.ontologia.session.MediosdetransportesFacade;
import com.ontologia.session.OrdenestrabajoFacade;
import com.ontologia.session.PaquetesFacade;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *
 * @author Sebastian Rojas
 */
@WebServlet(name = "codigoServlet", urlPatterns = {"/codigoServlet"})
public class codigoServlet extends HttpServlet {

  @EJB
  private OrdenestrabajoFacade ordenestrabajoFacade;

  @EJB
  private MediosdetransportesFacade mediosdetransportesFacade;

  @EJB
  private PaquetesFacade paquetesFacade;

  @EJB
  private MediosdepropulsionFacade mediosdepropulsionFacade;

  @EJB
  private ConceptosFacade conceptosFacade;

  String error = "";
  String respuesta = "";
  boolean bandera = true;
  private List<String> vCodigo;
  private ArrayList<List<String>> vTerminos = new ArrayList<List<String>>();

  /**
   * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
   * methods.
   *
   * @param request servlet request
   * @param response servlet response
   * @throws ServletException if a servlet-specific error occurs
   * @throws IOException if an I/O error occurs
   */
  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    try (PrintWriter out = response.getWriter()) {
      HttpSession session = request.getSession();
      if (bandera) {
        session.setAttribute("error", error);
      } else {
        session.setAttribute("respuesta", respuesta);
      }
      response.sendRedirect("respuesta.jsp");
    }
    vTerminos.clear();
  }

  // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
  /**
   * Handles the HTTP <code>GET</code> method.
   *
   * @param request servlet request
   * @param response servlet response
   * @throws ServletException if a servlet-specific error occurs
   * @throws IOException if an I/O error occurs
   */
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
    processRequest(request, response);
  }

  /**
   * Handles the HTTP <code>POST</code> method.
   *
   * @param request servlet request
   * @param response servlet response
   * @throws ServletException if a servlet-specific error occurs
   * @throws IOException if an I/O error occurs
   */
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
    try {
      String cadena = request.getParameter("codigo");
      this.dividirTerminos(cadena);
      for (List<String> s : vTerminos) {
        this.insertarTerminos(s);
      }

    } catch (NullPointerException e) {
      bandera = false;
      error = "por favor ingrese su codigo";
    }
    processRequest(request, response);
  }

  /**
   * Returns a short description of the servlet.
   *
   * @return a String containing servlet description
   */
  @Override
  public String getServletInfo() {
    return "Short description";
  }// </editor-fold>

  public void dividirTerminos(String codigo) {
    List<String> vLinea;
    ArrayList<Integer> vPosicionesConceptos = new ArrayList<>();
    vCodigo = Arrays.asList(codigo.split("[\\r\\n]+"));
    for (int i = 0; i < vCodigo.size(); i++) {
      Conceptos concepto = null;
      String fraseAnalizar = vCodigo.get(i);
      if (fraseAnalizar.substring(0, 1).equals("?") && i == 0) {
        bandera = false;
        error = "Debe crear primero conceptos";
        break;
      } else {
        vLinea = Arrays.asList(fraseAnalizar.split("\\s+"));
        if (vLinea.size() == 1) {
          concepto = conceptosFacade.existeConcepto(fraseAnalizar.toLowerCase());
          if (concepto == null) {
            bandera = false;
            error = "El concepto no existe reconocido";
          } else {
            vPosicionesConceptos.add((Integer) i);

          }
        }
      }
    }

    for (int i = 0; i < vPosicionesConceptos.size() - 1; i++) {
      List<String> lista = new Vector<String>();
      List<String> prelista = vCodigo.subList(vPosicionesConceptos.get(i).intValue(), vPosicionesConceptos.get(i + 1).intValue());
      String finConcepto = vCodigo.get(vPosicionesConceptos.get(i).intValue()).substring(6);
      lista.addAll(prelista);
      lista.add("fin" + finConcepto);
      if (lista.get(0).toString().contains("inicio") && lista.get(lista.size() - 1).toString().contains("fin")) {
        insertarTerminos(lista);
      } else if (lista.get(0).toString().contains("?")) {
        respuesta += this.calcularRespuesta(lista.get(0).toString());
      }
    }
  }

  public void insertarTerminos(List<String> terminos) {
    Mediosdepropulsion medio = new Mediosdepropulsion();
    Paquetes paquete = new Paquetes();
    Mediosdetransportes medioTransporte = new Mediosdetransportes();
    Ordenestrabajo ordenTrabajo = new Ordenestrabajo();
    String termino = "";
    OUTER:
    for (int i = 0; i < terminos.size(); i++) {
      if ("inicio".equals(terminos.get(i).toLowerCase().substring(0, 6))) {
        termino = terminos.get(i).toLowerCase();
      }
      if (i != terminos.size() - 1) {
        if (termino.equals("iniciomediodepropulsion") && i != 0) {
          List<String> vAtributos = Arrays.asList(terminos.get(i).split("="));
          if (vAtributos.get(0).toLowerCase().replace(" ", "").equals("descripcion") && !"fin".equals(terminos.get(i).toLowerCase().substring(0, 3))) {
            medio.setDescripcion(vAtributos.get(1));
          } else {
            error += "atributo desconocido [" + vAtributos.get(0) + "] para la creacion de: " + termino;
            bandera = false;
            break OUTER;
          }
        } else if (termino.equals("iniciopaquete") && i != 0) {
          List<String> vAtributos = Arrays.asList(terminos.get(i).split("="));
          if (!"fin".equals(terminos.get(i).toLowerCase().substring(0, 3))) {
            switch (vAtributos.get(0).toLowerCase().replace(" ", "")) {
              case "peso":
                paquete.setPeso(Integer.parseInt(vAtributos.get(1).replace(" ", "")));
                break;
              case "tamano":
                paquete.setTamano(Integer.parseInt(vAtributos.get(1).replace(" ", "")));
                break;
              default:
                error += "atributo desconocido [" + vAtributos.get(0) + "] para la creacion de: " + termino;
                bandera = false;
                break OUTER;
            }
          }
        } else if (termino.equals("iniciomediodetransporte") && i != 0) {
          List<String> vAtributos = Arrays.asList(terminos.get(i).split("="));
          if (!"fin".equals(terminos.get(i).toLowerCase().substring(0, 3))) {
            switch (vAtributos.get(0).toLowerCase().replace(" ", "")) {
              case "descripcion":
                medioTransporte.setDescripcion(vAtributos.get(1).replace(" ", ""));
                break;
              case "velocidadmedia":
                medioTransporte.setVelocidadMedia(Integer.parseInt(vAtributos.get(1).replace(" ", "")));
                break;
              case "idmediopropulsion":
                Mediosdepropulsion medioP = new Mediosdepropulsion();
                medioP = mediosdepropulsionFacade.getMedioPropulsionDescripcion(vAtributos.get(1).replace(" ", ""));
                try {
                  medioTransporte.setIdMedioPropulsion(medioP);
                } catch (NullPointerException e) {
                  error += "No existe el medio de propulsion que selecciono por favor verifique";
                }
                break;
              case "capacidadcarga":
                medioTransporte.setCapacidadCarga(Integer.parseInt(vAtributos.get(1).replace(" ", "")));
                break;
              case "medidacontenedor":
                medioTransporte.setMedidaContenedor(Integer.parseInt(vAtributos.get(1).replace(" ", "")));
                break;
              default:
                error += "atributo desconocido [" + vAtributos.get(0) + "] para la creacion de: " + termino;
                bandera = false;
                break OUTER;
            }
          }
        } else if (termino.equals("inicioordentrabajo") && i != 0) {
          List<String> vAtributos = Arrays.asList(terminos.get(i).split("="));
          if (!"fin".equals(terminos.get(i).toLowerCase().substring(0, 3))) {
            switch (vAtributos.get(0).toLowerCase().replace(" ", "")) {
              case "tiempoentrega":
                ordenTrabajo.setTiempoEntrega(Integer.parseInt(vAtributos.get(1).replace(" ", "")));
                break;
              case "lugarentrega":
                ordenTrabajo.setLugarEntrega(vAtributos.get(1).replace(" ", ""));
                break;
              case "descripcion":
                ordenTrabajo.setDescripcion(vAtributos.get(1).replace(" ", ""));
                break;
              case "pesopaquete":
                Paquetes p = new Paquetes();
                p = paquetesFacade.getPaquetePorPeso(vAtributos.get(1).replace(" ", ""));
                ordenTrabajo.setIdPaquete(paquete);
                break;
              default:
                error += "atributo desconocido [" + vAtributos.get(0) + "] para la creacion de: " + termino;
                bandera = false;
                break OUTER;
            }
          }
        }
      }
    }
    if (bandera) {
      switch (termino) {
        case "iniciomediodepropulsion":
          mediosdepropulsionFacade.guardarMedioPropulsion(medio);
          break;
        case "iniciopaquete":
          paquetesFacade.guardarPaquete(paquete);
          break;
        case "iniciomediodetransporte":
          mediosdetransportesFacade.guardarMedioDeTransporte(medioTransporte);
          break;
        case "inicioordentrabajo":
          ordenestrabajoFacade.guardarOrdenesDeTrabajo(ordenTrabajo);
          break;
      }
    }
  }

  public String calcularRespuesta(String pregunta) {
    String respuesta = "";
    List<String> vLinea;
    boolean bBandera = true;
    Conceptos concepto = null;
    Mediosdetransportes medioT = new Mediosdetransportes();
    Paquetes paqueteT = new Paquetes();
    vLinea = Arrays.asList(pregunta.split("\\s+"));
    for (int i = 0; i < vLinea.size(); i++) {
      String posibleConcepto = vLinea.get(i);
      concepto = conceptosFacade.existeConcepto(posibleConcepto);
      if (concepto != null) {
        if (i == 0) {
          String atributo = vLinea.get(i + 1);
          switch (atributo) {
            case "max":
              atributo = "max" + atributo;
              break;
            case "maximo":
              atributo = "max" + atributo;
              break;
            case "min":
              atributo = "min" + atributo;
              break;
            case "minimo":
              atributo = "min" + atributo;
              break;
            default:
              bBandera = false;
              break;
          }
          if (bBandera) {
            switch (concepto.getDescripcion()) {
              case "mediotransporte":
                medioT = mediosdetransportesFacade.getMedioTransportePorAtributo(atributo);
                if (medioT != null) {
                  respuesta = "el maximo medio de transporte por " + atributo + " es: " + medioT.getDescripcion();
                } else {
                  error += "no existen el conceptos para " + concepto.getDescripcion();
                }
                break;
                case "paquete":
                  paqueteT = paquetesFacade.getPaquetePorAtributo(atributo);
                  if(paqueteT != null) {
                    respuesta = "el maximo medio de transporte por " + atributo + " es: " + medioT.getDescripcion();
                  } else {
                    error += "no existen el conceptos para " + concepto.getDescripcion();
                  }
            }
          }
        }
      }
    }

    return respuesta;
  }
}
